#!/usr/bin/perl
use strict;

#données
my $dossier = $ARGV[0];
my $lot_test = 0;
my ($ligne, $mot, $cat, $lemme, $occur, @spr, $file, @dos, $compt, $dos_s, $file_d, @file, $fileres);
my $temp;
my %classif_lemme; #beta
my %compt_lemme; #occurences des lemmes par fichiers
my %compt_files_lemme; #occurences totales de lemmes par fichier
my %compt_classe_lemme; #occurences totales de lemmes par classe
my %etiquettes; #etiquettes
my %new_etiquettes; #nouvelles etiquettes calculées
my %nombre_docs; #nombre de documents, par classe et total
my %appartenances; #quels mots dans quels fichiers;
my %choix_alea; #découpage du corpus en lots
my $doc_ap = 0; #nombre de documents pour apprentissage
my $doc_test = 0; #nombre de documents pour test
my $epsilon = 0.01; #variable de "lissage" (evitement des 0)
my $lot = 1; #lot test de départ
my $iter = 1; #numero du classifieur en cours

$nombre_docs{"0-star"} = 135;
$nombre_docs{"1-star"} = 283;
$nombre_docs{"2-star"} = 394;
$nombre_docs{"3-star"} = 173;
$nombre_docs{"unsupervised"} = 4021;
$nombre_docs{"total"} = $nombre_docs{"0-star"} + $nombre_docs{"1-star"} + $nombre_docs{"2-star"} + $nombre_docs{"3-star"};

#Lecture des dossiers
opendir(DIR, $dossier) || die "can't opendir $dossier: $!";
  @spr = grep { /^supervised$/ } readdir(DIR);
closedir DIR;

#Récupération des lots de docs via un fichier de lots
sub load_lots(){
	my $file = "lots_".$lot;
	open TT, $file or die "Cannot open $file\n";
	while($ligne = <TT>) {
		if($ligne=~ /^(.*)\t(.*)$/){
			my $fil = $1; my $lot = $2;
			$choix_alea{$fil} = $lot;
			if($lot == $lot_test){ $doc_test++;}
			else{ $doc_ap++;}
		}
	}
	print "Lots charges: $doc_ap docs apprentissage, $doc_test docs test\n";
}

#Récupération des differents comptes dans le corpus
sub classif_bayesien()
{
	my $tot3 = 0;
	print "Classif...\n";
	#parcours les dossiers
	foreach my $element (@spr){
		my $element2 = $dossier."/".$element;
		if($element2 eq $dossier."/supervised"){
	    		opendir(DIR, $element2) || die "can't opendir $element2: $!";
			print "Traitement de $element2 ...\n";
			@dos = grep { /star/ } readdir(DIR);
	    		closedir DIR;
		}
		else{ @dos = $element2; }
	
		foreach $dos_s (@dos){
			my $dos_s2 = $element2."/".$dos_s;
			opendir(DIR, $dos_s2) || die "can't opendir $dos_s2: $!";
			print "Traitement de $dos_s2 ...\n";
			@file = grep { /txt.lemme$/ } readdir(DIR);
			closedir DIR;
			
					
			# chaque fichier
			foreach $file_d (@file){
				my $file_d2 = $dos_s2."/".$file_d;
				
				#On récupère les etiquettes des documents supervisés
				if($file_d2 =~ /0-star/){
					$etiquettes{$file_d2} = "0&1-star";
				}
				if($file_d2 =~ /1-star/){
					$etiquettes{$file_d2} = "0&1-star";
				}
				if($file_d2 =~ /2-star/){
					$etiquettes{$file_d2} = "2&3-star";
				}
				if($file_d2 =~ /3-star/){
					$etiquettes{$file_d2} = "2&3-star";
				}
				
				open TT, $file_d2 or die "Cannot open $file_d2\n";
				while($ligne = <TT>) {
					if($ligne=~ /^(.*)\t(.*)\t(.*)$/){
						$mot = $1; $cat = $2; $lemme = $3;
						if((($cat) !~ /,/) && (($cat) !~ /:/) && (($cat) !~ /SENT/) && (($cat) !~ /''/)){
							if(!exists($appartenances{$file_d2}{$lemme})){
								$appartenances{$file_d2}{$lemme} = 1;
							}
							#nombre de lemmes dans chaque fichier
							if(exists($compt_files_lemme{$file_d2})){
								$compt_files_lemme{$file_d2}++;
							}
							else{
								$compt_files_lemme{$file_d2}=1;
							}
							#occurrences du lemme dans chaque fichier
							if(exists($compt_lemme{$lemme}{$file_d2})){
								$compt_lemme{$lemme}{$file_d2}++;
							}
							else{
								$compt_lemme{$lemme}{$file_d2}=1;
							}
						}
					}
				}
			}
		}
	}

	#On récupère le nombre de lemmes par classe
	$compt_classe_lemme{"0&1-star"}=0;
	$compt_classe_lemme{"2&3-star"}=0;
	
	foreach my $file (keys(%compt_files_lemme)){
		if($file =~ /0-star/){
			$compt_classe_lemme{"0&1-star"} += $compt_files_lemme{$file};
		}
		if($file =~ /1-star/){
			$compt_classe_lemme{"0&1-star"} += $compt_files_lemme{$file};
		}
		if($file =~ /2-star/){
			$compt_classe_lemme{"2&3-star"} += $compt_files_lemme{$file};
		}
		if($file =~ /3-star/){
			$compt_classe_lemme{"2&3-star"} += $compt_files_lemme{$file};
		}
	}

}

#Calcul des betas: fréquences en occurences, non normalisées
sub calcul_parametres(){
	print "Début param...\n";
	
	foreach my $element (keys(%compt_lemme)){
		
		my $a=0;
		my $b=0;
		my $tot3 = 0;
		foreach $file(keys(%{$compt_lemme{$element}})){
			#on utilise que les lots d'apprentissage
			if($choix_alea{$file} != $lot_test){
				if($etiquettes{$file} eq "0&1-star"){
					$a += $compt_lemme{$element}{$file};
				}
				else{
					if($etiquettes{$file} eq "2&3-star"){
						$b += $compt_lemme{$element}{$file};
					}
				}
			}
		}
		
		#on évite les 0
		if($a == 0){ $a = $epsilon;}
		if($b == 0){ $b = $epsilon;}
		
		$classif_lemme{$element}{"0&1-star"} = $a / $compt_classe_lemme{"0&1-star"};
		$classif_lemme{$element}{"2&3-star"} = $b / $compt_classe_lemme{"2&3-star"};
	}
	print "Fin param...\n";
}

#etiquetage des données avec les paramètres calculés
sub etiquetage(){
	$fileres = "Etiquetage.txt";
	my $reussite = 0;
	my $compt_file = 0;
	foreach my $element2 (@spr){
		my $element2 = $dossier."/".$element2;
		if($element2 eq $dossier."/supervised"){
	    		opendir(DIR, $element2) || die "can't opendir $element2: $!";
			print "Traitement de $element2 ...\n";
			@dos = grep { /star/ } readdir(DIR);
	    		closedir DIR;
		}
		else{ @dos = $element2; }
	
		foreach my $dos_s2 (@dos){
			$dos_s2 = $element2."/".$dos_s2;
			opendir(DIR, $dos_s2) || die "can't opendir $dos_s2: $!";
			print "Traitement de $dos_s2 ...\n";
			@file = grep { /lemme$/ } readdir(DIR);
			closedir DIR;
			
					
			# chaque fichier
			foreach my $file_d2 (@file){
				$file_d2 = $dos_s2."/".$file_d2;
				
				#on ne traite que les documents du lot de test
				if($choix_alea{$file_d2} == $lot_test){
					$compt_file++;
					my %res;
					$res{"0&1-star"}=0;
					$res{"2&3-star"}=0;
					
					
					foreach $lemme (keys(%classif_lemme)){
						if(exists($compt_lemme{$lemme}{$file_d2})){
							$res{"0&1-star"} = $res{"0&1-star"} + $compt_lemme{$lemme}{$file_d2} * log($classif_lemme{$lemme}{"0&1-star"});
							$res{"2&3-star"} = $res{"2&3-star"} + $compt_lemme{$lemme}{$file_d2} * log($classif_lemme{$lemme}{"2&3-star"});
						}
					}
					
					#on trie les resultats dans l'ordre décroissant, et on prendra le max
					my @resFinal = (sort { $res{$b} <=> $res{$a} } keys(%res));
					#on vient de trouver une nouvelle etiquette
					$new_etiquettes{$file_d2} = $resFinal[0];
					#print $file_d2."\t.$new_etiquettes{$file_d2}.\n";
				}
			}
		}
	}
	
	#variable qui compte combien de documents sont bien ré-étiquetés
	my $good = 0;
	my $tot2 = 0;
	#on sauvegarde ces nouvelles étiquettes que l'on utisera à l'étape suivante
	open (N_ETIQ, ">new_etiquettes_hierarchique_1_lot_".$lot."_test_$lot_test") or die "Can't open new_etiquettes!\n";
	
	foreach my $el (keys(%etiquettes)){
		if($choix_alea{$el} == $lot_test){
			$tot2++;
			print N_ETIQ $el."\t".$new_etiquettes{$el}."\n";
			if($etiquettes{$el} eq $new_etiquettes{$el}){
				$good += 1;
			}
		}
	}
	print "\n? ".$tot2." = ".$compt_file." ?\tGood: $good\n";
	#on fait la moyenne
	$good /= $tot2;

	print "Reussite: ".$good."\n";
	print RES "$good\n";
	
	close(N_ETIQ);
}


######## Main #####################
classif_bayesien();

#on boucle sur les 10 différents lots de test possibles
while($lot<=10){
print "Lot $lot...\n";
$doc_ap = 0;
$doc_test = 0;
$lot_test = 0;
load_lots();
my $fileres = "Resultats_croises_metrique_".$epsilon."_lot_".$lot;
open(RES, ">$fileres") or die "Can't open $fileres!\n";
while($lot_test<10){
	%new_etiquettes = {};
	calcul_parametres();
	etiquetage();
	$lot_test++;
}
close(RES);
print "Fin lot $lot...\n";
$lot++;
}
